package com.gin.kotlin.no_gay_alliance.argument

import android.os.Parcelable
import androidx.annotation.IntRange
import com.gin.kotlin.no_gay_alliance.argument.TopicListArgument.Type
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.AbstractTopicListFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.ColListFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.FavorTopicListFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.ForumListFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.ForumRecommendFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.TopicSearchFragment
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.UserSearchFragment
import com.gin.kotlin.no_gay_alliance.model.SearchAreaModel
import com.gin.nga.enums.param.OrderByParam
import com.gin.nga.enums.param.SearchContent
import kotlinx.parcelize.Parcelize
import okhttp3.HttpUrl.Companion.toHttpUrl

/**
 * 主题列表参数
 */
@Parcelize
data class TopicListArgument(
    /**
     * 打开的页面类型
     */
    val type: Type,
    /**
     * 页码,
     */
    @IntRange(from = 1) val page: Int? = null,
    /**
     * 合集ID,当 type 为 [Type.COL_LIST] 或 [Type.COL_SEARCH] 时有效
     */
    val colTid: Long? = null,
    /**
     * 排序方式, 从 [com.gin.nga.enums.param.OrderByParam] 中选择，当 type 为 [Type.COL_LIST] 或 [Type.FORUM_LIST] 时有效
     */
    val orderBy: String? = null,
    /**
     * 收藏夹ID，当 type 为 [Type.FAVOR_FOLDER] 时有效，填1表示查看当前用户的默认收藏夹
     */
    val folderId: Long? = null,
    /**
     * 版面ID，当 type 为 [Type.FORUM_LIST] 或 [Type.FORUM_SEARCH] 或 [Type.FORUM_RECOMMEND] 或 [Type.USER_SEARCH] 时有效
     */
    val forumId: Long? = null,
    /**
     * 搜索关键字，当 type 为 [Type.COL_SEARCH] 或 [Type.FORUM_SEARCH]  时有效
     */
    val keyword: String? = null,

    /**
     * 作者UID，当 type 为 [Type.USER_SEARCH] 时有效
     */
    val authorUid: Long? = null,
    /**
     * 是否搜索用户的回复，当 type 为 [Type.USER_SEARCH] 时有效
     */
    val searchReply: Boolean? = null,
    /**
     * 是否搜索主楼正文，当 type 为 [Type.COL_SEARCH] 或 [Type.FORUM_SEARCH]  时有效
     */
    val searchContent: SearchContent? = null,
    /**
     * 是否只搜索精华帖，当 type 为 [Type.COL_SEARCH] 或 [Type.FORUM_SEARCH]  时有效
     */
    val recommendOnly: Boolean? = null,
    /**
     * 临时标题
     */
    val title: String? = null,
    /**
     * 搜索目标版面，当 type 为 [Type.FORUM_SEARCH]  时有效
     */
    val forumIds: List<Long>? = null,
    /**
     * 搜索区域，当 type 为 [Type.COL_SEARCH] 或 [Type.FORUM_SEARCH]  时有效
     */
    val searchAreas: List<SearchAreaModel>? = null,
) : Parcelable {
    fun orderByParam() = OrderByParam.entries.firstOrNull { it.value == this.orderBy }

    companion object {
        /**
         * 解析一个URL来生成参数
         * @param url String
         * @return TopicListArgument
         */
        fun parseUrl(url: String?): TopicListArgument? {
            val httpUrl = url?.toHttpUrl() ?: return null

            val page = httpUrl.queryParameter("page")?.toInt()
            val colTid = httpUrl.queryParameter("stid")?.toLong()
            val folderId = httpUrl.queryParameter("favor")?.toLong()
            val authorUid = httpUrl.queryParameter("authorid")?.toLong()
            val orderBy = httpUrl.queryParameter("order_by")
            val keyword = httpUrl.queryParameter("keyword")
            val searchReply = httpUrl.queryParameter("searchpost") != null
            val recommendOnly = httpUrl.queryParameter("recommend") != null
            val searchContent = httpUrl.queryParameter("content")
                ?.toIntOrNull()
                ?.let { v -> SearchContent.entries.firstOrNull { it.value == v } }
            // 不含逗号的情况
            val forumId = httpUrl.queryParameter("fid")?.takeIf { !it.contains(',') }?.toLong()
            val forumIds = httpUrl.queryParameter("fid")?.takeIf { it.contains(',') }?.split(',')?.map { it.toLong() }
            // 判断类型
            val type = when {
                folderId != null -> Type.FAVOR_FOLDER
                authorUid != null -> Type.USER_SEARCH
                keyword != null -> if (colTid != null) Type.COL_SEARCH else Type.FORUM_SEARCH
                recommendOnly -> Type.FORUM_RECOMMEND
                else -> if (colTid != null) Type.COL_LIST else Type.FORUM_LIST
            }
            return TopicListArgument(
                type,
                page,
                colTid,
                orderBy,
                folderId,
                forumId,
                keyword,
                authorUid,
                searchReply,
                searchContent,
                recommendOnly,
                null,
                forumIds
            )
        }
    }


    /**
     * 类型
     */
    @Parcelize
    enum class Type(
        /**
         * Fragment的实例化方法
         */
        val newInstance: (argument: TopicListArgument) -> AbstractTopicListFragment<*>,
    ) : Parcelable {
        /**
         * 收藏夹
         */
        FAVOR_FOLDER({ FavorTopicListFragment.newInstance(it) }),

        /**
         * 合集浏览
         */
        COL_LIST({ ColListFragment.newInstance(it) }),

        /**
         * 合集搜索
         */
        COL_SEARCH({ TopicSearchFragment.newInstance(it) }),

        /**
         * 版面浏览
         */
        FORUM_LIST({ ForumListFragment.newInstance(it) }),

        /**
         * 版面搜索
         */
        FORUM_SEARCH({ TopicSearchFragment.newInstance(it) }),

        /**
         * 版面精华
         */
        FORUM_RECOMMEND({ ForumRecommendFragment.newInstance(it) }),

        /**
         * 用户发言
         */
        USER_SEARCH({ UserSearchFragment.newInstance(it) }), ;

    }
}